import type { IProgram, IProgramStatus } from "@/lib/types";
import { Form, InputNumber, Modal, Radio, Switch } from "antd";
import {
  forwardRef,
  useImperativeHandle,
  useRef,
  useState,
  type Ref,
} from "react";

export type EditType =
  | "cycle"
  | "time"
  | "temperature"
  | "humidity"
  | "pressure"
  | "ts";

type EditProgramModalProps = {
  visible: boolean;
  onClose: () => void;
  type?: EditType;
  records?: IProgramStatus[];
  onEditRecordsFinish?: (records: IProgramStatus[]) => void;
};
const titleMap: Record<EditType, string> = {
  cycle: "循环",
  humidity: "湿度",
  pressure: "压力",
  temperature: "温度",
  time: "时间",
  ts: "TS",
};
type FormRef<T = IProgramStatus | IProgram> = {
  confirm: () => Partial<T>;
};
export default function EditProgramModal(props: EditProgramModalProps) {
  const { visible, onClose, type, records, onEditRecordsFinish } = props;
  const formRef = useRef<FormRef>(null);

  function handleConfirm() {
    const newData = formRef.current?.confirm();
    records &&
      onEditRecordsFinish?.(
        records.map((record) => ({ ...record, ...newData }) as IProgramStatus),
      );
    onClose();
  }

  return (
    <Modal
      open={visible}
      title={type ? titleMap[type] : undefined}
      onCancel={onClose}
      onOk={handleConfirm}
      destroyOnClose
    >
      {type === "cycle" && <CycleForm records={records!} ref={formRef} />}
      {type === "time" && <TimeForm records={records!} ref={formRef} />}
      {type === "temperature" && (
        <TemperatureForm records={records!} ref={formRef} />
      )}
      {type === "humidity" && <HumidityForm records={records!} ref={formRef} />}
      {type === "pressure" && <PressureForm records={records!} ref={formRef} />}
      {type === "ts" && <TSForm records={records!} ref={formRef} />}
    </Modal>
  );
}

function useEditStateWithRef<T>(ref: Ref<FormRef<T>>, initialData: Partial<T>) {
  const [data, setData] = useState(initialData);

  useImperativeHandle(ref, () => {
    return {
      confirm() {
        return data;
      },
    };
  }, [data]);

  return [data, setData] as const;
}

type EditStatusFormProps = {
  records: IProgramStatus[];
};

const CycleForm = forwardRef<FormRef, EditStatusFormProps>(
  function CycleForm(props, ref) {
    const { records } = props;
    const [data, setData] = useEditStateWithRef<IProgramStatus>(ref, {
      segmentLoop: records[0].segmentLoop,
    });

    return (
      <Form>
        <Form.Item label={`段 ${records[0].segmentNo} [循环数]`}>
          <InputNumber
            className="w-full"
            value={data.segmentLoop}
            onChange={(v) => setData({ segmentLoop: v || undefined })}
          />
        </Form.Item>
      </Form>
    );
  },
);

const TimeForm = forwardRef<FormRef, EditStatusFormProps>(
  function TimeForm(props, ref) {
    const { records } = props;
    const [data, setData] = useEditStateWithRef<IProgramStatus>(ref, {
      stepHour: records[0].stepHour,
      stepMinute: records[0].stepMinute,
      stepSecond: records[0].stepSecond,
    });

    return (
      <Form layout="inline">
        <div className="flex">
          <Form.Item label="时">
            <InputNumber
              min={0}
              value={data.stepHour}
              onChange={(v) =>
                setData((p) => ({
                  ...p,
                  stepHour: v || 0,
                }))
              }
            />
          </Form.Item>
          <Form.Item label="分">
            <InputNumber
              min={0}
              max={59}
              value={data.stepMinute}
              onChange={(v) =>
                setData((p) => ({
                  ...p,
                  stepMinute: v || 0,
                }))
              }
            />
          </Form.Item>
          <Form.Item label="秒">
            <InputNumber
              min={0}
              max={59}
              value={data.stepSecond}
              onChange={(v) =>
                setData((p) => ({
                  ...p,
                  stepSecond: v || 0,
                }))
              }
            />
          </Form.Item>
        </div>
      </Form>
    );
  },
);

const TemperatureForm = forwardRef<FormRef, EditStatusFormProps>(
  function TemperatureForm(props, ref) {
    const { records } = props;
    const [data, setData] = useEditStateWithRef<IProgramStatus>(ref, {
      stepTSv: records[0].stepTSv,
      stepIsT: records[0].stepIsT,
      stepTRateValue: records[0].stepTRateValue,
      stepTIsRate: records[0].stepTIsRate,
      // stepTIsWait: records[0].stepTIsWait,
    });
    return (
      <Form labelCol={{ flex: "0 0 110px" }}>
        <Form.Item label="目标值 ℃">
          <div className="flex items-center gap-x-4">
            <InputNumber
              className="flex-auto"
              value={data.stepTSv}
              onChange={(v) => setData((p) => ({ ...p, stepTSv: v || 0 }))}
            />
            <Switch
              value={data.stepIsT === "1"}
              onChange={(v) =>
                setData((p) => ({ ...p, stepIsT: v ? "1" : "0" }))
              }
            />
          </div>
        </Form.Item>
        <Form.Item label="斜率">
          <Switch
            value={data.stepTIsRate === "1"}
            onChange={(v) =>
              setData((p) => ({ ...p, stepTIsRate: v ? "1" : "0" }))
            }
          />
        </Form.Item>
        {/* <Form.Item label="等待">
          <Switch
            value={data.stepTIsWait === "1"}
            onChange={(v) =>
              setData((p) => ({ ...p, stepTIsWait: v ? "1" : "0" }))
            }
          />
        </Form.Item> */}
      </Form>
    );
  },
);

const HumidityForm = forwardRef<FormRef, EditStatusFormProps>(
  function HumidityForm(props, ref) {
    const { records } = props;
    const [data, setData] = useEditStateWithRef<IProgramStatus>(ref, {
      stepHSv: records[0].stepHSv,
      stepIsH: records[0].stepIsH,
      stepHRateValue: records[0].stepHRateValue,
      stepHIsRate: records[0].stepHIsRate,
      // stepHIsWait: records[0].stepHIsWait,
    });
    return (
      <Form labelCol={{ flex: "0 0 110px" }}>
        <Form.Item label="目标值 %">
          <div className="flex items-center gap-x-4">
            <InputNumber
              className="flex-auto"
              value={data.stepHSv}
              onChange={(v) => setData((p) => ({ ...p, stepHSv: v || 0 }))}
            />
            <Switch
              value={data.stepIsH === "1"}
              onChange={(v) =>
                setData((p) => ({ ...p, stepIsH: v ? "1" : "0" }))
              }
            />
          </div>
        </Form.Item>
        <Form.Item label="斜率">
          <Switch
            value={data.stepHIsRate === "1"}
            onChange={(v) =>
              setData((p) => ({ ...p, stepHIsRate: v ? "1" : "0" }))
            }
          />
        </Form.Item>
        {/* <Form.Item label="等待">
          <Switch
            value={data.stepHIsWait === "1"}
            onChange={(v) =>
              setData((p) => ({ ...p, stepHIsWait: v ? "1" : "0" }))
            }
          />
        </Form.Item> */}
      </Form>
    );
  },
);

const PressureForm = forwardRef<FormRef, EditStatusFormProps>(
  function PressureForm(props, ref) {
    const { records } = props;
    const [data, setData] = useEditStateWithRef<IProgramStatus>(ref, {
      stepPUnit: records[0].stepPUnit,
      stepPSv: records[0].stepPSv,
      stepIsP: records[0].stepIsP,
      stepPRateValue: records[0].stepPRateValue,
      stepPIsRate: records[0].stepPIsRate,
      // stepPIsWait: records[0].stepPIsWait,
    });
    return (
      <div>
        <div className="flex justify-center">
          <Radio.Group
            value={data.stepPUnit}
            onChange={(e) =>
              setData((p) => ({
                ...p,
                stepPUnit: parseInt(e.target.value),
              }))
            }
          >
            <Radio.Button value={1}>Pa</Radio.Button>
            <Radio.Button value={1000}>kPa</Radio.Button>
          </Radio.Group>
        </div>
        <Form className="mt-4" labelCol={{ flex: "0 0 110px" }}>
          <Form.Item label={`目标值 ${data.stepPUnit === 1 ? "Pa" : "kPa"}`}>
            <div className="flex items-center gap-x-4">
              <InputNumber
                className="flex-auto"
                value={data.stepPSv}
                onChange={(v) => setData((p) => ({ ...p, stepPSv: v || 0 }))}
              />
              <Switch
                value={data.stepIsP === "1"}
                onChange={(v) =>
                  setData((p) => ({ ...p, stepIsP: v ? "1" : "0" }))
                }
              />
            </div>
          </Form.Item>
          <Form.Item label={`斜率`}>
            <Switch
              value={data.stepPIsRate === "1"}
              onChange={(v) =>
                setData((p) => ({ ...p, stepPIsRate: v ? "1" : "0" }))
              }
            />
          </Form.Item>
          {/* <Form.Item label="等待">
            <Switch
              value={data.stepPIsWait === "1"}
              onChange={(v) =>
                setData((p) => ({ ...p, stepPIsWait: v ? "1" : "0" }))
              }
            />
          </Form.Item> */}
        </Form>
      </div>
    );
  },
);

const TSForm = forwardRef<FormRef, EditStatusFormProps>(
  function TSForm(props, ref) {
    const { records } = props;
    const [data, setData] = useEditStateWithRef<IProgramStatus>(ref, {
      stepTs: records[0].stepTs,
    });
    return (
      <Form
        colon={false}
        labelCol={{ flex: "0 0 60px" }}
        className="grid grid-cols-3 justify-center"
      >
        {[1, 2, 3, 4, 5, 6, 7, 8].map((index) => (
          <Form.Item key={index} label={index}>
            <Switch
              value={data.stepTs![index - 1] === "1"}
              onChange={(v) =>
                setData({
                  stepTs: data
                    .stepTs!.split("")
                    .map((s, i) => (i + 1 === index ? (v ? "1" : "0") : s))
                    .join(""),
                })
              }
            />
          </Form.Item>
        ))}
      </Form>
    );
  },
);
